R tiene una inmensa capacidad de graficar y visualizar datos de todo tipo, incluídos datos genéticos.

Las gráficas pueden hacerse desde la base de R (base) o con paquetes especializados en graficar, como ggplot2 y ggbio. También paquetes especializados en un tipo de datos que incluyen funciones para graficar, como ape para árboles filogenéticos.

En esta sección veremos una introducción a graficar en R usando graphics que es el sistema que viene con base y luego con ggplot2.

Una de las mejores formas de aprender a hacer gráficas en R es buscar en internet/libro una gráfica parecida a la que queremos hacer y ver el código. Algunas recomendaciones:

Acordeón de colores para tener a la mano: * R puede trabajar con paletas de colores pre-establecidas, chécalas en este link. * No te pierdas cómo nombrar muchos otros colores y utilizar otras paletas con más colores en la R Color Reference Sheet. * Si necesitas generar muchos colores o colores amigables con la banda daltónica I wanthue es lo que necesitas.

Base Graphics

Estas son las principales funciones para graficar utilizando la base de R. Puedes buscar ayuda de cada una con su nombre, y además en explorar argumentos extras con ?par

Gráficas x,y:

Dando x, y:

largo<-c(10,20,11,15,16,20)
ancho<-c(5,10,7,8,8,11)
plot(x=largo, y=ancho)

Dando un objeto que tiene dos columnas, se toman automático como x,y:

# ver el contenido de `cars`(una df ejemplo que viene con R)
head(cars)
##   speed dist
## 1     4    2
## 2     4   10
## 3     7    4
## 4     7   22
## 5     8   16
## 6     9   10
plot(cars)

Si queremos especificar qué columnas serán x, y del objeto:

# graficar vel vs distancia
plot(x=cars$speed, y=cars$dist)

Cambiar título de ejes e íconos:

# graficar vel vs distancia
plot(x=cars$speed, y=cars$dist, xlab="Velocidad", ylab="Distancia", cex=0.5, pch=19)

Ejercicio: mira la ayuda de par y explica qué hacen los argumentos cex y pch.

Ejercicio: Repite la figura anterior pero cambiando los puntos por triángulos azules. Necesitarás esto.

Histogramas

Los histogramas sirven para representar la frecuencia de los valores de datos numéricos. Por ejemplo los datos islands que vienen pre-cargados tienen el nombre y tamaño de las islas del mundo:

head(islands)
##       Africa   Antarctica         Asia    Australia Axel Heiberg       Baffin 
##        11506         5500        16988         2968           16          184

Con un histograma podemos ver que la mayor parte de las islas son pequeñas y que hay unas cuantas grandes:

hist(x=islands)

Con el argumento breaks podemos cambiar la cantidad de rangos en las que dividir el histograma.

hist(x=islands, breaks=5)

Podemos escribir hist(islands) porque islands es un vector. Si tuviéramos los datos en una data.frame entonces hay que especificar de qué columna queremos el histograma:

hist(cars$speed)

Barplot

Podemos hacer gráficas de barras con base en un vector una dataframe donde tengamos datos con la "altura" de las barras, por ejemplo los datos islands que vienen pre-cargados:

# ver los datos de los primeros 6 elementos de islands
islands[1:6]
##       Africa   Antarctica         Asia    Australia Axel Heiberg       Baffin 
##        11506         5500        16988         2968           16          184
# Hacer un barplot con los primeros elementos de islands.
barplot(islands[1:6], ylab="tamaño")

ggplot2

Las gráficas que hemos visto hasta ahora pueden verse un poco feas de inicio y puede tomar un rato y mucho código arreglarlas a algo hermoso. ggplot2 es un paquete que ahorra este trabajo y que ahora es ampliamente adoptado.

ggplot2 construye gráficas "definiendo sus componentes paso a paso".

Para poder usar ggplot2 se requiere que la data.frame esté en formato largo. Puedes revisar estos apuntes para entender más sobre qué es "el formato largo".

Términos importantes:

Ojo: Mucho mejor que ver la ayuda de cada función es ver el R Graphics Cookbook u otros recursos en línea.

El mejor recurso para aprender a usar ggplot2 a profundidad El libro online de ggplot2

Y para familiarizarte con lo que puede hacer ggplot2 y sus argumentos, imprime y pon bajo la almohada su [acordeón]https://raw.githubusercontent.com/rstudio/cheatsheets/main/data-visualization.pdf)

Una gráfica de ggplot se puede guardar en un objeto de r, e irle sumando a dicho objeto otros elementos, con +.

Para ver la estructura de una gráfica en ggplot2 vamos a hacer una figura icónica de coalsencia: la probabilidad de que dos individuos tengan un ancestro común en la generación anterior es 1/2Ne.

Comencemos por crear los datos que queremos graficar:

# Crear un vector del 1 al 20 para el Ne
Ne<-c(1:20)
Ne
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
# Crear un vector con el resultado de 1/Ne
p.shared.ancestor<-1/(2*Ne)
p.shared.ancestor
##  [1] 0.50000000 0.25000000 0.16666667 0.12500000 0.10000000 0.08333333
##  [7] 0.07142857 0.06250000 0.05555556 0.05000000 0.04545455 0.04166667
## [13] 0.03846154 0.03571429 0.03333333 0.03125000 0.02941176 0.02777778
## [19] 0.02631579 0.02500000
# ponerlos como columnas de una df
x<-data.frame(Ne, p.shared.ancestor)
head(x)
##   Ne p.shared.ancestor
## 1  1        0.50000000
## 2  2        0.25000000
## 3  3        0.16666667
## 4  4        0.12500000
## 5  5        0.10000000
## 6  6        0.08333333

Ahora hgamos una figura en ggplot2:

# Cargar ggplot2
library(ggplot2) # recuerda que esto se hace solo una vez al inicio de tu script o cuando vayas a inciar a usar la paquetaría

# definir datos que quiero graficar
ggplot(data=x, aes(x=Ne, y=p.shared.ancestor)) + # el más sirve para decir que le voy a agregar algo más al comando de ggplot2
  # poner puntos
  geom_point() +  
  # poner línea que conecta los puntos
  geom_line() + 
  # ponerle título bonito al eje y
  ylab("Probabilidad de compartir \n un ancestro en la generación previa") # "\n" sirve para que el texto aparezca en dos renglones

Más Ejemplos:

Gráficas de dispersión con más detalle

# Examinar datos pre-cargados
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
# graficar 
ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) + geom_point()

Pregunta: ¿Qué hace el símbolo +? Nota que el código anterior tmb puede escribirse así:

myplot<-ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width))

myplot + geom_point()

Es decir, podemos guardar una gráfia de ggplot2 en un objeto y sumarle nuevos cambios después.

Los colores y formas se cambian en aes:

ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width, color= Species, shape=Species)) + geom_point()

Ya sea en el aes de la función inicial o dentro de los geoms (Nota que el tamaño no es un aes, sino un argumento de geom_point)

ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) + 
    geom_point(aes(color= Species, shape=Species), size=3)

Si queremos quitar el fondo gris podemos cambiar al tema blanco y negro, con theme_bw():

ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) + 
    geom_point(aes(color= Species, shape=Species), size=3) + 
    theme_bw()

Aveces queremos graficar en páneles separados la misma info para diferentes tratamientos o especies. Por ejemplo:

ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width)) + 
  geom_point() +
  facet_grid(Species ~ .)

Ejercicio Pon color por especie a la gráfica anterior para que se vea así:

Ejercicio Repite la gráfica anterior pero para que se vea así:

Podemos repetir una de las figuras anteriores pero cambiando los labels para que digan "Ancho de sépalo" y "Largo de sépalo", respectivamente. Así:

# gráfico base
p <- ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width,     
                          color=Species)) + 
            geom_point()
# Cambiar texto de los ejes:
p + ylab("Ancho del sépalo") + xlab("Largo del sépalo")  

También podemos agregar el resultado de un modelo matemático, como una regresión lineal:

ggplot(data=iris, aes(x=Sepal.Length, y= Sepal.Width, color=Species)) + 
  geom_point() +
  facet_grid(Species ~ .) +
  geom_smooth(method="lm")
## `geom_smooth()` using formula 'y ~ x'

Barplot

En este tipo de gráficas la altura de las barras puede significar dos cosas:

  • la cuenta (frecuencia) de casos de cada valor de x. Si quieres graficar esto en los argumentos de geom_bar utiliza stat="bin" para variables continuas y stat="count" para variables categóricas.
  • el valor de la columna en el set de datos. Si quieres graficar esto utiliza stat="identity" en los argumentos de geom_bar.

Ejemplo con los datos de maíces que descargamos de: Arteaga, María Clara et al. (2015), Data from: Genomic variation in recently collected maize landraces from Mexico, Dryad, Dataset, https://doi.org/10.5061/dryad.4t20n

# leer datos asumiendo que están en tu WD
maices<-read.delim("maizteocintle_SNP50k_meta_extended.txt")

Gráfica de número de muestras por estado. Es decir que "cuente" cuantas muestras hay en cada estado y que esa sea la altura de la barra:

p.estados <- ggplot(data = maices,# utiliza los datos maíces
       aes(x=Estado)) + # que los estados sean las barras
  geom_bar(stat="count")  # que la altura de las barras sea "la cuenta" de las veces que aparece cada estado en las muestras

p.estados # ver gráfica

# poner los nombres de los estados en vertical para que se lea mejor
p.estados + theme(axis.text.x = element_text(angle = 90))

Ejercicio: Lee el tutorial de este link y utilizalo para repetir la gráfica anterior, pero ordenando los estados (ahorita están en orden alfabético, ponlos en cualquier otro orden que quieras).

Si queremos hacer un barplot con el valor de los datos usamos stat="identity"

# datos de juguete
chocolate <- data.frame(x = c("A", "B", "C", "D", "E"),
                   y = c(10, 20, 5, -10, 25))

#plot
ggplot(chocolate, aes(x, y)) +                                     # Create basic barchart
  geom_bar(stat = "identity")

Histograma

Los hisogramas requieren que le demos en el eje x un vector numérico sobre el cual queremos ver la distribución de sus datos (count) en Y.

ggplot(data=maices, aes(x=Altitud)) + # queremos que los datos sean la altitud
                     geom_histogram() # queremos un histograma
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Podemos ajustar el ancho de las barras con el argumento binwidth. Las unidades son las mismas en las que está tu variable del eje x.

ggplot(data=maices, aes(x=Altitud)) + # queremos que los datos sean la altitud
    geom_histogram(binwidth = 50) # binwidth cada 50 metros

Boxplot

Siguiendo con los datos de maíces anteriores:

# plot
# utiliza los datos maices
p.altitud <- ggplot(data=maices,  
            # en X las categorías de altitud (bajo, medio, alto)
            # en Y la altitud de las muestras en cada categoría
            aes(x=Categ.Altitud, y=Altitud)) +
            # queremos un boxplot
             geom_boxplot()
p.altitud

Podemos agregar puntos sobre los boxplots para visualizar mejor cuántos datos hay en cada categoría:

p.altitud + geom_jitter()

Cambiar colores en ggplot

Al igual que en base, en ggplot es posible cambiar los colores manualmente o cambiando la paleta.

Recomiendo buscar más información y ejemplos en esta excelente guía Cookbook-R colores en ggplot2.

Ejemplos:

Cambiar colores manualmente

# mismo boxplot de hace rato
ggplot(data=maices,  
            aes(x=Categ.Altitud, y=Altitud, 
                fill=Categ.Altitud)) + # especificamos que el relleno de los boxplots será por Categ.Altitud
            geom_boxplot() +
scale_fill_manual(values=c("red", "blue", "green")) # decimos qué colores queremos manualmente

Cambiar la paleta

# Crear paleta apta para daltónicos:
cbPalette <- c("#999999", "#E69F00", "#56B4E9", "#009E73")

# Usar paleta en gráfica:
ggplot(data=maices,  
            aes(x=Categ.Altitud, y=Altitud, 
                fill=Categ.Altitud)) + # especificamos que el relleno de los boxplots será por Categ.Altitud
            geom_boxplot() +
scale_fill_manual(values=cbPalette) # le damos la paleta

Usar una paleta de ColorBrewer

ggplot(data=maices,  
            aes(x=Categ.Altitud, y=Altitud, 
                fill=Categ.Altitud)) + # especificamos que el relleno de los boxplots será por Categ.Altitud
            geom_boxplot() +
scale_fill_brewer(palette="Set1") # tomamos una paleta predefinida de las que vienen con ggplot2

Utilizar gradientes de colores

Primero hagamos una gráfica que se preste a un gradiente de colores:

# Graficar altitud vs latitud
ggplot(maices, aes(x=Latitud, y=Altitud, 
                   colour=Altitud)) + # especificiar que el color será por altitud
geom_point()

Ahora cambiemos el gradiente:

# misma gráfica de arriba
 ggplot(maices, aes(x=Latitud, y=Altitud, 
                   colour=Altitud)) + 
       geom_point() +
# pero cambiando el color
    scale_colour_gradientn(colours=terrain.colors(6)) # terrain.colors es una de las paletas predefindas de ggplot2, puedes buscar más googleando

Hacer más grande el texto

En tus presentaciones, artículos y tesis por favor asegúrate de que todo el texto de tu figura se vea bien. Como tip, cuando la pegues en un documento de texto, la letra más chica no debe ser menor al texto que escribas en tamaño de fuente 8 ó 10 (preferentemente 10) justo debajo de la figura.

En ggplot2 puedes especificar el tamaño de cada elemento de texto (título, leyenda, ejes...) o simplemente agrandarlo todo de un jalón. Ejemplos:

Agrandar todo el texto:

# misma gráfica de arriba
p<-ggplot(maices, aes(x=Latitud, y=Altitud, 
                   colour=Altitud)) + geom_point()
p

# agrandar TODO el texto
p + theme(text=element_text(size=20))

O agrandar solo un texto se interés, por ejemplo el títulod de los ejes:

p + theme(axis.title=element_text(size=20))

Ejercicio: busca cómo se llaman los demás elementos de texto, por ejemplo el texto de los ejes (los numeritos en este caso)

Múltiples gráficas (=/= facets) en una gráfica:

Veamos este ejemplo de R Cookbook sobre mutlipltos:

Primero generamos y guardamos en objetos 4 gráficas:

# This example uses the ChickWeight dataset, which comes with ggplot2
# First plot
p1 <- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet, group=Chick)) +
    geom_line() +
    ggtitle("Growth curve for individual chicks")

# Second plot
p2 <- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet)) +
    geom_point(alpha=.3) +
    geom_smooth(alpha=.2, size=1) +
    ggtitle("Fitted growth curve per diet")

# Third plot
p3 <- ggplot(subset(ChickWeight, Time==21), aes(x=weight, colour=Diet)) +
    geom_density() +
    ggtitle("Final weight, by diet")

# Fourth plot
p4 <- ggplot(subset(ChickWeight, Time==21), aes(x=weight, fill=Diet)) +
    geom_histogram(colour="black", binwidth=50) +
    facet_grid(Diet ~ .) +
    ggtitle("Final weight, by diet") +
    theme(legend.position="none")        # No legend (redundant in this graph)    

Luego las graficamos juntas con la función multiplot, del paquete Rmisc (que es la misma que viene en link de arriba y que tmb puedes copiar y pegar en tu script):

`

library(Rmisc)
## Loading required package: lattice
## Loading required package: plyr
## Warning: package 'plyr' was built under R version 3.5.2
multiplot(p1, p2, p3, p4, cols=2)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Guardar imágenes:

Método 1:

  • "Abrir un device" con png(), jpg(), pdf() según el formato en que queramos guardar.
  • Hacer la gráfica
  • "Cerrar el device" con dev.off

Nota para que esto funcione dentro de un chunck de código, tienes que correr las 3 líneas juntas (seleccionadas) en vez de una por una.

png("borrame.png")
multiplot(p1, p2, p3, p4, cols=2)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
dev.off()
## quartz_off_screen 
##                 2

Si incluyes esto cuando corras tu script remotamente (eg en un cluster) o cuanlo "tejas" aun html, las gráficas se guardarán con los nombres que les digas y en el directorio que especifiques :)

Método 2:

En R studio darle "Export" o "Copy" en el panel de la imagen y seleccionar un nombre de archivo y demás características.

Método 3:

En ggplot2 puedes usar la función ggsave() para guardar uno de tus plots. Por default se guarda el último que corriste:

ggplot(maices, aes(x=Latitud, y=Altitud, 
                   colour=Altitud)) + geom_point()

ggsave(filename = "borrame2.png")
## Saving 7 x 5 in image

También puedes especificar otro plot y ajustar tamaño y resolución (últil porque algunas revistas te van a pedir los plots en pdf y 300 dpi...)

# definir que queremos el plot de uno que guardamos en el objeto p.altitud por ahí arriba
ggsave(plot=p.altitud, file="borrame3.png",
       width = 15, height=12, units="cm",
       dpi=300)